﻿Public Class Animator

	Shared Sub Run(Obj As Object, Prop As String, Min As Double, Max As Double, Speed As Double, Target As Double)
		Dim A As New Animation
		A.Key = TypeName(Obj) & "." & Obj.GetHashCode & "." & Prop
		A.Object = Obj
		A.Property = Prop
		A.Minimum = Min
		A.Maximum = Max
		A.Speed = Speed
		A.Target = Target
		If Animations.ContainsKey(A.Key) Then
			Dim Old = Animations(A.Key)
			Old.Stop()
			Animations.Remove(Old.Key)
			Old = Nothing
		End If
		Animations.Add(A.Key, A)
		A.Start()
	End Sub

	Class Animation

		Friend Key As String
		Friend [Object] As Object
		Friend [Property] As String
		Friend Minimum As Double
		Friend Maximum As Double
		Friend Speed As Double
		Friend Target As Double
		Dim StartValue As Double
		Dim SpeedFactor As Double
		Dim WithEvents Timer As New Timer With {.Interval = 20}
		Dim Watch As New Stopwatch
		Sub Start()
			SpeedFactor = (Maximum - Minimum) / Speed
			StartValue = CallByName([Object], [Property], CallType.Get)
			Timer.Start()
			Watch.Start()
		End Sub
		Sub [Stop]()
			Timer.Enabled = False
			Application.DoEvents()
		End Sub

		Private Sub Timer_Tick(sender As Object, e As System.EventArgs) Handles Timer.Tick
			Dim NewValue = StartValue + Math.Sign(Target - StartValue) * (Watch.ElapsedMilliseconds / 1000) * SpeedFactor
			If Target > StartValue And NewValue >= Target Then NewValue = Target
			If Target < StartValue And NewValue <= Target Then NewValue = Target
			CallByName([Object], [Property], CallType.Set, NewValue)
			If NewValue = Target Then Timer.Enabled = False
			If Not Timer.Enabled Then Animations.Remove(Key)
		End Sub

	End Class

	Shared Animations As New SortedList(Of String, Animation)

End Class
